#include <func.h>

#define BACKLOG 10

int tcp_listen(char* port) 
{
    struct addrinfo hints;
    bzero(&hints, sizeof(hints));
    hints.ai_flags = AI_PASSIVE;        // 通配符地址
    hints.ai_family = AF_INET;          // IPv4
    hints.ai_socktype = SOCK_STREAM;    // TCP

    struct addrinfo* result;
    int err = getaddrinfo(NULL, port, &hints, &result);
    if (err) {
        fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(err));
        return -1;
    }

    // 1. 创建主动套接字
    int sockfd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (sockfd == -1) {
        return -1;
    }

    // 2. 绑定地址
    struct addrinfo* curr = result;
    for(; curr != NULL; curr = curr->ai_next) {
        if (bind(sockfd, curr->ai_addr, curr->ai_addrlen) == -1) {
            continue;
        }
        break;
    }
    if (curr == NULL) {
        return -1;
    }

    freeaddrinfo(result);
    
    // 3. 将主动套接字变成被动套接字
    if (listen(sockfd, BACKLOG) == -1) {
        return -1;
    }

    return sockfd;
}

int main(int argc, char* argv[])
{
    // 服务器端
    int listenfd = tcp_listen("9527");
    if (listenfd == -1) {
        error(1, errno, "tcp_listen()");
    }
    printf("INFO: server listen port: 9527\n");

    struct sockaddr_storage addr;
    socklen_t len = sizeof(addr);
    printf("accept前: len=%d\n", len);
    int connfd = accept(listenfd, (struct sockaddr*)&addr, &len);   // 阻塞点
    printf("accept后: len=%d\n", len);

    return 0;
}

